package com.yao;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Properties;

import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Color;
import java.awt.Insets;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingWorker;
import javax.swing.JButton;
import javax.swing.JFileChooser;

/**
 * 构建页面GUI
 */
public class Gui {

    private JFrame frame = null;
    private JTextField srcPathText = null;
    private JTextField toPathText = null;
    private File srcFile = null;
    private File toFile = null;
    private JLabel tipLabel = null;
    private JFileChooser chooser = null; // 文件选择框
    private boolean compressing = false; // 是否正在压缩
    private Properties appConfig = null;
    private JTextField imgWidthText = null; // 调整图片宽输入框
    private JTextField imgHeightText = null; // 调整图片高输入框

    public Gui() {
        JFrame.setDefaultLookAndFeelDecorated(false); // 使用 windows 风格窗体

        // 创建窗口(JFrame)
        frame = new JFrame("图片压缩");
        frame.setResizable(false); // 禁止拉伸以及放大按钮
        frame.setSize(550, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 设置窗口可关闭
        frame.setLocationRelativeTo(null); // 设置在屏幕中间显示

        // 创建容器
        JPanel panel = new JPanel();
        panel.setLayout(new GridBagLayout()); // 设置窗口布局
        frame.add(panel);

        // 渲染容器布局
        render(panel);

        loadProperties(); // 加载配置文件
    }

    /**
     * 渲染布局容器
     */
    private void render(JPanel panel) {
        // 创建布局约束
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(10, 10, 0, 10); // 设置每一个单元格4个内边距
        gbc.fill = GridBagConstraints.VERTICAL;

        /* 图片宽高比配置行 */
        gbc.gridy = 0;

        gbc.gridx = 0;
        JLabel imageWhLabel = new JLabel("调整图片尺寸：");
        panel.add(imageWhLabel, gbc);

        gbc.gridx = 1;
        JPanel imgPanel = new JPanel();
        JLabel imgWLabel = new JLabel("宽：");
        imgPanel.add(imgWLabel);
        imgWidthText = new JTextField(3);
        imgWidthText.setDocument(new IntegerDocument());
        imgWidthText.setMargin(new Insets(2, 2, 2, 2)); // 设置文本到四周的边距
        imgPanel.add(imgWidthText);
        JLabel imgHLabel = new JLabel(" * 高：");
        imgPanel.add(imgHLabel);
        imgHeightText = new JTextField(3);
        imgHeightText.setDocument(new IntegerDocument());
        imgHeightText.setMargin(new Insets(2, 2, 2, 2)); // 设置文本到四周的边距
        imgPanel.add(imgHeightText);
        JLabel tooltipLabel = new JLabel("?");
        tooltipLabel.setToolTipText("根据输入的宽高，将图片等比例缩放。");
        imgPanel.add(tooltipLabel);
        panel.add(imgPanel, gbc);

        // 第2行
        gbc.gridy = 1;

        gbc.gridx = 0;
        JLabel srcLabel = new JLabel("待压缩图片：");
        panel.add(srcLabel, gbc);

        // 第2列
        gbc.gridx = 1;
        gbc.insets = new Insets(10, 10, 0, 5); // 设置每一个单元格4个内边距
        srcPathText = new JTextField(25);
        srcPathText.setEditable(false);
        srcPathText.setMargin(new Insets(2, 2, 2, 2)); // 设置文本到四周的边距
        panel.add(srcPathText, gbc);

        // 第3列
        gbc.gridx = 2;
        gbc.insets = new Insets(10, 0, 0, 5); // 设置每一个单元格4个内边距
        JButton srcBtn = new JButton("浏览");
        srcBtn.addActionListener(e -> fileChooser(0));
        panel.add(srcBtn, gbc);

        // 第2行
        gbc.gridy = 2;

        gbc.gridx = 0;
        gbc.insets = new Insets(10, 10, 0, 10); // 设置每一个单元格4个内边距
        JLabel toLabel = new JLabel("保存目录：");
        panel.add(toLabel, gbc);

        // 第2列
        gbc.gridx = 1;
        gbc.insets = new Insets(10, 10, 0, 5); // 设置每一个单元格4个内边距
        toPathText = new JTextField(25);
        toPathText.setEditable(false);
        toPathText.setMargin(new Insets(2, 2, 2, 2)); // 设置文本到四周的边距
        panel.add(toPathText, gbc);

        // 第3列
        gbc.gridx = 2;
        gbc.insets = new Insets(10, 0, 0, 5); // 设置每一个单元格4个内边距
        JButton toBtn = new JButton("浏览");
        toBtn.addActionListener(e -> fileChooser(1));
        panel.add(toBtn, gbc);

        // 开始压缩按钮
        gbc.gridy = 3;
        gbc.gridx = 0;
        gbc.insets = new Insets(10, 10, 0, 10); // 设置每一个单元格4个内边距
        JButton button = new JButton("压缩");
        button.addActionListener(e -> {
            if (compressing == false) { // 没有上传，则进行上传
                if (srcFile == null) {
                    tipLabel.setForeground(Color.orange);
                    tipLabel.setText("请选择压缩图片");
                } else if (toFile == null) {
                    tipLabel.setForeground(Color.orange);
                    tipLabel.setText("请选择保存目录！");
                } else {
                    compressing = true;
                    tipLabel.setForeground(Color.blue);
                    tipLabel.setText("图片压缩中……");
                    imageCompress(); // 进行图片压缩
                }
            }
        });
        panel.add(button, gbc);

        // 创建文件选择器
        chooser = new JFileChooser();

        // 压缩提示框
        gbc.gridx = 1;
        tipLabel = new JLabel();
        tipLabel.setForeground(Color.green);
        panel.add(tipLabel, gbc);
    }

    /**
     * 显示 GUI
     */
    public void show() {
        frame.setVisible(true); // 设置界面可见
    }

    /**
     * 文件选择器
     */
    private void fileChooser(int flag) {
        chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); // 选择文件夹
        if (flag == 0) {
            chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
            // 设置选择图片文件
            chooser.addChoosableFileFilter(new ImageFilter());
            chooser.setAcceptAllFileFilterUsed(false);
            chooser.setCurrentDirectory(srcFile); // 设置当前文件
        }
        int result = -1;
        if (flag == 0) {
            result = chooser.showOpenDialog(frame);
        } else {
            result = chooser.showSaveDialog(frame);
        }
        if (result == JFileChooser.APPROVE_OPTION) { // 点击确定按钮
            File tmpFile = chooser.getSelectedFile();
            String selectedPath = tmpFile.getAbsolutePath();
            if (flag == 0) { // 选择的是初始目录
                srcFile = tmpFile;
                srcPathText.setText(selectedPath);
            } else {
                toFile = tmpFile;
                toPathText.setText(selectedPath);
            }
        }
    }

    /**
     * 加载配置信息
     */
    private void loadProperties() {
        SwingWorker<Properties, Object> configWorker = new SwingWorker<Properties, Object>() {
            @Override
            protected Properties doInBackground() {
                Properties config = new Properties();
                try (FileInputStream fis = new FileInputStream(Utils.CONFIG_PATH)) {
                    config.loadFromXML(fis);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return config;
            }

            @Override
            protected void done() {
                try {
                    appConfig = get();
                    imgWidthText.setText(appConfig.getProperty("imageWidth"));
                    imgHeightText.setText(appConfig.getProperty("imageHeight"));
                    String imagePath = appConfig.getProperty("imagePath");
                    if (imagePath != null) {
                        srcFile = new File(imagePath);
                        srcPathText.setText(imagePath);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
        configWorker.execute();
    }

    /**
     * 后台线程进行图片压缩
     */
    private void imageCompress() {
        String imgWidth = imgWidthText.getText();
        String imgHeight = imgHeightText.getText();
        SwingWorker<HashMap<String, Object>, Integer> compressWorker = new SwingWorker<HashMap<String, Object>, Integer>() {
            @Override
            protected HashMap<String, Object> doInBackground() {
                int width = 0;
                int height = 0;
                if (!imgWidth.equals("")) {
                    width = Math.abs(Integer.valueOf(imgWidth).intValue());
                }
                if (!imgHeight.equals("")) {
                    height = Math.abs(Integer.valueOf(imgHeight).intValue());
                }
                appConfig.setProperty("imageWidth", String.valueOf(width));
                appConfig.setProperty("imageHeight", String.valueOf(height));
                appConfig.setProperty("imagePath", srcFile.getAbsolutePath());
                HashMap<String, Object> map = new HashMap<String, Object>();
                map.put("width", width);
                map.put("height", height);
                try (FileOutputStream fos = new FileOutputStream(Utils.CONFIG_PATH)) {
                    Utils.compress(width, height, srcFile, toFile);
                    appConfig.storeToXML(fos, "缓存配置", "utf-8");
                    map.put("code", 0);
                } catch (IOException e) {
                    map.put("code", -1);
                    map.put("msg", e.getMessage());
                }
                return map;
            }

            @Override
            protected void done() {
                try {
                    HashMap<String, Object> map = get();
                    int code = (int) map.get("code");
                    imgWidthText.setText(map.get("width").toString());
                    imgHeightText.setText(map.get("height").toString());
                    if (code == -1) {
                        throw new Exception(map.get("msg").toString());
                    } else {
                        tipLabel.setForeground(Color.green);
                        tipLabel.setText("图片压缩成功!");
                    }
                } catch (Exception e) {
                    tipLabel.setForeground(Color.red);
                    tipLabel.setText(e.getMessage());
                } finally {
                    compressing = false;
                }
            }
        };
        compressWorker.execute();
    }

}
